iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
Web 3

Web3 X 公共財系列 第 16

Day 16 - Allo libraries內及 Factory 的合約

  • 分享至 

  • xImage
  •  

clone.sol

主要與strategies.sol互動
A helper library to create deterministic clones of the strategy contracts when a pool is created

library Clone {
    function createClone(address _contract, uint256 _nonce) internal returns (address) {
        bytes32 salt = keccak256(abi.encodePacked(msg.sender, _nonce));
        return ClonesUpgradeable.cloneDeterministic(_contract, salt);
    }
}

Error.sol

處理所有Revert

contract Errors {
    /// ======================
    /// ====== Generic =======
    /// ======================

    error INVALID();
    error MISMATCH();
    error NOT_ENOUGH_FUNDS();
    error UNAUTHORIZED();
    error ZERO_ADDRESS();

    /// ======================
    /// ====== Registry ======
    /// ======================

    /// @dev Thrown when the nonce passed has been used or not available
    error NONCE_NOT_AVAILABLE();

    /// @dev Thrown when the 'msg.sender' is not the pending owner on ownership transfer
    error NOT_PENDING_OWNER();

    /// @dev Thrown if the anchor creation fails
    error ANCHOR_ERROR();

    /// ======================
    /// ======== Allo ========
    /// ======================

    /// @notice Thrown when the strategy is not approved
    error NOT_APPROVED_STRATEGY();

    /// @notice Thrown when the strategy is approved and should be cloned
    error IS_APPROVED_STRATEGY();

    /// @notice Thrown when the fee is below 1e18 which is the fee percentage denominator
    error INVALID_FEE();

    /// ======================
    /// ===== IStrategy ======
    /// ======================

    error ALREADY_INITIALIZED();
    error NOT_INITIALIZED();
    error INVALID_ADDRESS();
    error POOL_INACTIVE();
    error POOL_ACTIVE();
    error ARRAY_MISMATCH();
    error INVALID_REGISTRATION();
    error INVALID_METADATA();
    error RECIPIENT_NOT_ACCEPTED();
    error RECIPIENT_ALREADY_ACCEPTED();
    error REGISTRATION_NOT_ACTIVE();
    error RECIPIENT_ERROR(address recipientId);
    error ALLOCATION_NOT_ACTIVE();
    error ALLOCATION_NOT_ENDED();
    error ALLOCATION_ACTIVE();
}

Metadata.sol

Metadata is used to define the metadata for the protocol that is used throughout the system.
定義一個Struct 包含Protocol(IPFS = 1) 及 pointer

struct Metadata {
    /// @notice Protocol ID corresponding to a specific protocol (currently using IPFS = 1)
    uint256 protocol;
    /// @notice Pointer (hash) to fetch metadata for the specified protocol
    string pointer;
}

Native.sol

This is used to define the address of the native token for the protocol

address public constant NATIVE = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

Transfer.sol

A helper contract to transfer tokens within Allo protocol
引入 上面的Native.sol 及utils/SafeTransferLib.sol

contract Transfer is Native {
    /// @notice Thrown when the amount of tokens sent does not match the amount of tokens expected
    error AMOUNT_MISMATCH();

    /// @notice This holds the details for a transfer
    struct TransferData {
        address from;
        address to;
        uint256 amount;
    }

    /// Transfer an amount of a token to an array of addresses
    function _transferAmountsFrom(address _token, TransferData[] memory _transferData) internal returns (bool) {
        uint256 msgValue = msg.value;

        for (uint256 i; i < _transferData.length;) {
            TransferData memory transferData = _transferData[i];

            if (_token == NATIVE) {
                msgValue -= transferData.amount;
                SafeTransferLib.safeTransferETH(transferData.to, transferData.amount);
            } else {
                SafeTransferLib.safeTransferFrom(_token, transferData.from, transferData.to, transferData.amount);
            }

            unchecked {
                i++;
            }
        }

        if (msgValue != 0) revert AMOUNT_MISMATCH();

        return true;
    }

    ///  Transfer an amount of a token to an address
    function _transferAmountFrom(address _token, TransferData memory _transferData) internal returns (bool) {
        uint256 amount = _transferData.amount;
        if (_token == NATIVE) {
            // Native Token
            if (msg.value < amount) revert AMOUNT_MISMATCH();

            SafeTransferLib.safeTransferETH(_transferData.to, amount);
        } else {
            SafeTransferLib.safeTransferFrom(_token, _transferData.from, _transferData.to, amount);
        }
        return true;
    }

    /// Transfer an amount of a token to an address
    function _transferAmount(address _token, address _to, uint256 _amount) internal {
        if (_token == NATIVE) {
            SafeTransferLib.safeTransferETH(_to, _amount);
        } else {
            SafeTransferLib.safeTransfer(_token, _to, _amount);
        }
    }
}
struct TransferData {
        address from;
        address to;
        uint256 amount;
}

factory/ ContractFactory.sol

引用昨天提到的CREATE3
contractFactory is used internally to deploy our contracts using CREATE3

contract ContractFactory {
    /// ======================
    /// ======= Errors =======
    /// ======================

    /// Thrown when the requested salt has already been used.
    error SALT_USED();

    ///  Thrown when the caller is not authorized to deploy.
    error UNAUTHORIZED();

    /// ======================
    /// ======= Events =======
    /// ======================

    /// Emitted when a contract is deployed.
    event Deployed(address indexed deployed, bytes32 indexed salt);

    /// ======================
    /// ======= Storage ======
    /// ======================

    /// Collection of used salts.
    mapping(bytes32 => bool) public usedSalts;

    /// Collection of authorized deployers.
    mapping(address => bool) public isDeployer;

    /// ======================
    /// ======= Modifiers ====
    /// ======================

    ///  Modifier to ensure the caller is authorized to deploy and returns if not.
    modifier onlyDeployer() {
        _checkIsDeployer();
        _;
    }

    /// ======================
    /// ===== Constructor ====
    /// ======================

    ///  On deployment sets the 'msg.sender' to allowed deployer.
    constructor() {
        isDeployer[msg.sender] = true;
    }

    /// ===============================
    /// ====== Internal Functions =====
    /// ===============================

    /// Checks if the caller is authorized to deploy.
    function _checkIsDeployer() internal view {
        if (!isDeployer[msg.sender]) revert UNAUTHORIZED();
    }

    /// ===============================
    /// ====== External Functions =====
    /// ===============================

    /// eploys a contract using CREATE3.
    function deploy(string memory _contractName, string memory _version, bytes memory creationCode)
        external
        payable
        onlyDeployer
        returns (address deployedContract)
    {
        // hash salt with the contract name and version
        bytes32 salt = keccak256(abi.encodePacked(_contractName, _version));

        // ensure salt has not been used
        if (usedSalts[salt]) revert SALT_USED();

        usedSalts[salt] = true;

        deployedContract = CREATE3.deploy(salt, creationCode, msg.value);

        emit Deployed(deployedContract, salt);
    }

    /// Set the allowed deployer.
    function setDeployer(address _deployer, bool _allowedToDeploy) external onlyDeployer {
        // Set the deployer to the allowedToDeploy mapping
        isDeployer[_deployer] = _allowedToDeploy;
    }
}

同步紀錄未來/學習solidity

好好了解Uniswap V1->V2->V3->V4,未來(這次鐵人賽結束)可以繼續了解常用Web3工具合約(主要是gnosis safe)


上一篇
Day 15 - Registry.sol
下一篇
Day 17 - BaseStrategy.sol
系列文
Web3 X 公共財30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言